package org.asiainfo.system.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import org.asiainfo.common.idempotent.annotation.RepeatSubmit;
import org.asiainfo.common.log.annotation.Log;
import org.asiainfo.common.log.enums.BusinessType;
import org.asiainfo.system.domain.bo.SysDeptBo;
import org.asiainfo.system.domain.bo.SysUserBo;
import org.asiainfo.system.domain.bo.SysUserRoleBo;
import org.asiainfo.system.domain.vo.SysDeptTreeSelectVo;
import org.asiainfo.system.domain.vo.SysUserVo;
import org.asiainfo.system.service.SysDeptService;
import org.springframework.validation.annotation.Validated;
import org.asiainfo.system.service.SysRoleService;
import org.asiainfo.system.domain.vo.SysRoleVo;
import org.asiainfo.system.domain.bo.SysRoleBo;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.asiainfo.common.mybatis.stream.core.page.PageQuery;
import org.asiainfo.common.mybatis.stream.core.page.TableDataInfo;
import org.asiainfo.common.core.domain.R;
import org.asiainfo.common.web.core.BaseController;
import jakarta.validation.constraints.*;
import org.asiainfo.common.core.validate.AddGroup;
import org.asiainfo.common.core.validate.EditGroup;

import java.util.List;

/**
 * 角色信息表
 *
 * @author dotor-ww
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/role")
public class SysRoleController extends BaseController {

    private final SysRoleService sysRoleService;

    private final SysDeptService sysDeptService;

    /**
     * 分页查询
     *
     * @param sysRoleBo 筛选条件
     * @param pageQuery 分页对象
     * @return 查询结果
     */
    @SaCheckPermission("system:role:list")
    @GetMapping("/list")
    public TableDataInfo<SysRoleVo> list(SysRoleBo sysRoleBo, PageQuery pageQuery) {
        return sysRoleService.queryPageList(sysRoleBo, pageQuery);
    }

    /**
     * 通过主键查询单条数据
     *
     * @param roleId 主键
     * @return 单条数据
     */
    @SaCheckPermission("system:role:query")
    @GetMapping("/{roleId}")
    public R<SysRoleVo> getInfo(@NotNull(message = "角色ID不能为空") @PathVariable("roleId") Long roleId) {
        sysRoleService.checkRoleDataScope(roleId);
        return R.ok(sysRoleService.queryById(roleId));
    }

    /**
     * 新增数据
     *
     * @param sysRoleBo 实体
     * @return 新增结果
     */
    @SaCheckPermission("system:role:add")
    @Log(title = "角色信息表", businessType = BusinessType.INSERT)
    @RepeatSubmit
    @PostMapping
    public R<Void> add(@Validated(AddGroup.class) @RequestBody SysRoleBo sysRoleBo) {
        sysRoleService.checkRoleAllowed(sysRoleBo);
        if (sysRoleService.checkRoleNameUnique(sysRoleBo)) {
            return R.fail("新增角色'" + sysRoleBo.getRoleName() + "'失败，角色名称已存在");
        } else if (sysRoleService.checkRoleKeyUnique(sysRoleBo)) {
            return R.fail("新增角色'" + sysRoleBo.getRoleName() + "'失败，角色权限已存在");
        }
        return toAjax(sysRoleService.insertByBo(sysRoleBo));
    }

    /**
     * 编辑数据
     *
     * @param sysRoleBo 实体
     * @return 编辑结果
     */
    @SaCheckPermission("system:role:edit")
    @Log(title = "角色信息表", businessType = BusinessType.UPDATE)
    @RepeatSubmit
    @PutMapping
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysRoleBo sysRoleBo) {
        sysRoleService.checkRoleAllowed(sysRoleBo);
        sysRoleService.checkRoleDataScope(sysRoleBo.getRoleId());
        if (sysRoleService.checkRoleNameUnique(sysRoleBo)) {
            return R.fail("修改角色'" + sysRoleBo.getRoleName() + "'失败，角色名称已存在");
        } else if (sysRoleService.checkRoleKeyUnique(sysRoleBo)) {
            return R.fail("修改角色'" + sysRoleBo.getRoleName() + "'失败，角色权限已存在");
        }
        return toAjax(sysRoleService.updateByBo(sysRoleBo));
    }

    /**
     * 删除数据
     *
     * @param roleIds 主键
     * @return 删除是否成功
     */
    @SaCheckPermission("system:role:remove")
    @Log(title = "角色信息表", businessType = BusinessType.DELETE)
    @DeleteMapping("/{roleIds}")
    public R<Void> remove(@NotEmpty(message = "角色ID不能为空") @PathVariable Long[] roleIds) {
        return toAjax(sysRoleService.deleteWithValidByIds(List.of(roleIds)));
    }

    /**
     * 角色状态更新
     *
     * @param sysRoleBo 角色信息
     * @return 更新结果
     */
    @SaCheckPermission("system:role:edit")
    @Log(title = "角色信息表", businessType = BusinessType.UPDATE)
    @RepeatSubmit
    @PutMapping("/changeStatus")
    public R<Void> changeStatus(@RequestBody SysRoleBo sysRoleBo) {
        sysRoleService.checkRoleAllowed(sysRoleBo);
        sysRoleService.checkRoleDataScope(sysRoleBo.getRoleId());
        return toAjax(sysRoleService.updateRoleStatusByRoleId(sysRoleBo));
    }

    /**
     * 获取角色选择框列表
     *
     * @return 下拉结果
     */
    @SaCheckPermission("system:role:query")
    @GetMapping("/optionSelect")
    public R<Object> optionSelect() {
        return R.ok(sysRoleService.optionSelect());
    }

    /**
     * 查询已分配的角色列表
     *
     * @param sysUserBo 用户信息
     * @param pageQuery 分页信息
     * @return 查询结果
     */
    @SaCheckPermission("system:role:list")
    @GetMapping("/auth/allocatedList")
    public TableDataInfo<SysUserVo> allocatedList(SysUserBo sysUserBo, PageQuery pageQuery) {
        return sysRoleService.selectAllocatedList(sysUserBo, pageQuery);
    }

    /**
     * 查询未分配的角色列表
     *
     * @param sysUserBo 用户信息
     * @param pageQuery 分页信息
     * @return 查询结果
     */
    @SaCheckPermission("system:role:list")
    @GetMapping("/auth/unAllocatedList")
    public TableDataInfo<SysUserVo> unAllocatedList(SysUserBo sysUserBo, PageQuery pageQuery) {
        return sysRoleService.selectUnAllocatedList(sysUserBo, pageQuery);
    }

    /**
     * 取消授权
     *
     * @param sysUserRoleBo 用户角色关联信息
     * @return 操作结果
     */
    @SaCheckPermission("system:role:edit")
    @Log(title = "角色信息表", businessType = BusinessType.GRANT)
    @RepeatSubmit
    @PutMapping("/auth/cancel")
    public R<Void> cancelAuthUser(@RequestBody SysUserRoleBo sysUserRoleBo) {
        return toAjax(sysRoleService.removeAuthUser(sysUserRoleBo));
    }

    /**
     * 批量取消授权
     *
     * @param roleId  角色ID
     * @param userIds 用户ID
     * @return 操作结果
     */
    @SaCheckPermission("system:role:edit")
    @Log(title = "角色信息表", businessType = BusinessType.GRANT)
    @RepeatSubmit
    @PutMapping("/auth/cancelBatch")
    public R<Void> cancelAuthUserBatch(Long roleId, Long[] userIds) {
        return toAjax(sysRoleService.removeAuthUsers(roleId, userIds));
    }

    /**
     * 批量选择用户
     *
     * @param roleId  角色ID
     * @param userIds 用户ID
     * @return 操作结果
     */
    @SaCheckPermission("system:role:edit")
    @Log(title = "角色信息表", businessType = BusinessType.GRANT)
    @PutMapping("/auth/selectBatch")
    public R<Void> selectAuthUserBatch(Long roleId, Long[] userIds) {
        return toAjax(sysRoleService.insertAuthUsers(roleId, userIds));
    }

    /**
     * 修改角色数据权限
     *
     * @param sysRoleBo 角色信息
     * @return 操作结果
     */
    @SaCheckPermission("system:role:edit")
    @Log(title = "角色信息表", businessType = BusinessType.GRANT)
    @PutMapping("/dataScopeRole")
    public R<Void> dataScopeRole(@RequestBody SysRoleBo sysRoleBo) {
        sysRoleService.checkRoleAllowed(sysRoleBo);
        sysRoleService.checkRoleDataScope(sysRoleBo.getRoleId());
        return toAjax(sysRoleService.authDataScope(sysRoleBo));
    }

    /**
     * 查询角色部门树列表
     *
     * @param roleId 角色ID
     * @return 查询结果
     */
    @SaCheckPermission("system:role:list")
    @GetMapping("/deptTree/{roleId}")
    public R<Object> deptTreeSelectByRoleId(@NotNull(message = "角色ID不能为空") @PathVariable Long roleId) {
        SysDeptTreeSelectVo sysDeptTreeSelectVo = new SysDeptTreeSelectVo(
            sysDeptService.selectDeptIdsByRoleId(roleId),
            sysDeptService.selectDeptTree(new SysDeptBo()));
        return R.ok(sysDeptTreeSelectVo);
    }
}

